home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / reqed / source / reqed.b < prev   
Encoding:
Text File  |  1998-10-04  |  49.7 KB  |  1,905 lines

  1. {*
  2. ** A Requester Editor for ACE programs.
  3. ** Copyright (C) 1998 David Benn
  4. ** 
  5. ** This program is free software; you can redistribute it and/or
  6. ** modify it under the terms of the GNU General Public License
  7. ** as published by the Free Software Foundation; either version 2
  8. ** of the License, or (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. **
  19. ** A requester (in this context, a window containing gadgets and text)
  20. ** can be designed on-screen. Code, in the form of an ACE subprogram, 
  21. ** is then generated to render it, await gadget activity and clean up.
  22. **
  23. ** The programmer can add code to act upon specific gadget activity 
  24. ** and possibly return information to the main program.
  25. **
  26. ** Author: David J Benn
  27. **   Date: 6th-8th,10th,15th-22nd,25th,26th January 1995,
  28. **       13th,14th,18th-20th February 1995,
  29. **       12th September 1996
  30. *}
  31.  
  32. DEFLNG a-z
  33.  
  34. STRING version SIZE 30
  35. version = "$VER: ReqEd 1.12 (12.09.96)"
  36.  
  37. {*
  38. ** General constants.
  39. *}
  40. CONST true     = -1&
  41. CONST false     = 0&
  42. CONST null     = 0&
  43. CONST default     = -1&
  44.  
  45. {*
  46. ** ASCII codes for special keys.
  47. *}
  48. CONST DEL_key     = 127
  49. CONST BKSPC_key = 8
  50. CONST ENTER_key = 13
  51.  
  52. {*
  53. ** Border constants.
  54. *}
  55. CONST NO_EDGE        = 0 
  56. CONST LEFT_EDGE        = 1 
  57. CONST RIGHT_EDGE    = 2 
  58. CONST TOP_EDGE        = 3 
  59. CONST BOTTOM_EDGE    = 4
  60. CONST EDGE_THICKNESS    = 2
  61.  
  62. {*
  63. ** Menu constants.
  64. *}
  65. CONST sDisable        = 0
  66. CONST sEnable        = 1
  67. CONST sCheck        = 2
  68.  
  69. CONST mProject        = 1
  70. CONST iProject        = 0
  71. CONST iExit         = 1    '..for Preview mode Project menu.
  72. CONST iNew        = 1    '..for Layout mode Project menu.
  73. CONST iOpen        = 2
  74. CONST iSave        = 3
  75. CONST iSaveAs        = 4
  76. CONST iToolBar        = 5
  77. CONST iSep1.1        = 6
  78. CONST iAbout        = 7
  79. CONST iQuit        = 8
  80.  
  81. CONST mWindow        = 2
  82. CONST iWindow        = 0
  83. CONST iRedraw        = 1
  84. CONST iPreview        = 2
  85. CONST iSep2.1        = 3
  86. CONST iSetId        = 4
  87. CONST iSetTitle        = 5
  88. CONST iSep2.2        = 6
  89. CONST iSizeGadget    = 7
  90. CONST iMoveable        = 8
  91. CONST iDepthGadget    = 9
  92. CONST iCloseGadget    = 10
  93. CONST iSmartRefresh    = 11
  94. CONST iBorderless    = 12
  95.  
  96. {*
  97. ** Gadget constants.
  98. *}
  99. CONST gButton        = 1
  100. CONST gString        = 2
  101. CONST gLongInt        = 3
  102. CONST gPotX        = 4
  103. CONST gPotY        = 5
  104. CONST gText        = 6
  105. CONST gRaisedBox    = 7
  106. CONST gRecessedBox    = 8
  107.  
  108. {*
  109. ** GUI Object List node "kinds" (note: values agree with gadget constants above).
  110. *}
  111. CONST headOfList     = 0
  112. CONST buttonGadget     = 1
  113. CONST stringGadget     = 2
  114. CONST longintGadget     = 3
  115. CONST potXGadget     = 4
  116. CONST potYGadget     = 5
  117. CONST staticText     = 6
  118. CONST raisedBevelBox    = 7
  119. CONST recessedBevelBox    = 8
  120.  
  121. {*
  122. ** Box styles.
  123. *}
  124. CONST NORMAL         = 0
  125. CONST RAISED         = 1
  126. CONST RECESSED         = 2
  127. CONST STRGAD         = 3
  128.  
  129. {*
  130. ** Miscellaneous constants.
  131. *}
  132. CONST toolWdw = 1
  133. CONST maxToolBarButtons = 8
  134.  
  135. {* 
  136. ** Structure definitions.
  137. *}
  138. STRUCT WindowStruct
  139.    ADDRESS  NextWindow
  140.    SHORTINT LeftEdge
  141.    SHORTINT TopEdge
  142.    SHORTINT xWidth
  143.    SHORTINT Height
  144.    SHORTINT MouseY
  145.    SHORTINT MouseX
  146.    SHORTINT MinWidth
  147.    SHORTINT MinHeight
  148.    SHORTINT MaxWidth
  149.    SHORTINT MaxHeight
  150.    LONGINT  Flags
  151.    ADDRESS  MenuStrip
  152.    ADDRESS  Title
  153.    ADDRESS  FirstRequest
  154.    ADDRESS  DMRequest
  155.    SHORTINT ReqCount
  156.    ADDRESS  WScreen
  157.    ADDRESS  RPort
  158.    BYTE     BorderLeft
  159.    BYTE     BorderTop
  160.    BYTE     BorderRight
  161.    BYTE     BorderBottom
  162.    ADDRESS  BorderRPort
  163.    ADDRESS  FirstGadget
  164.    ADDRESS  Parent
  165.    ADDRESS  Descendant
  166.    ADDRESS  Pointer
  167.    BYTE     PtrHeight
  168.    BYTE     PtrWidth
  169.    BYTE     XOffset
  170.    BYTE     YOffset
  171.    LONGINT  IDCMPFlags
  172.    ADDRESS  UserPort
  173.    ADDRESS  WindowPort
  174.    ADDRESS  MessageKey
  175.    BYTE     DetailPen
  176.    BYTE     BlockPen
  177.    ADDRESS  CheckMark
  178.    ADDRESS  ScreenTitle
  179.    SHORTINT GZZMouseX
  180.    SHORTINT GZZMouseY
  181.    SHORTINT GZZWidth
  182.    SHORTINT GZZHeight
  183.    ADDRESS  ExtData
  184.    ADDRESS  UserData
  185.    ADDRESS  WLayer
  186.    ADDRESS  IFont
  187. END STRUCT
  188.  
  189. STRUCT GUIObjType
  190.   SHORTINT kind
  191.   SHORTINT x1
  192.   SHORTINT y1
  193.   SHORTINT x2
  194.   SHORTINT y2
  195.   ADDRESS  theText
  196.   ADDRESS  fontName
  197.   SHORTINT fontHeight
  198.   SHORTINT textStyle
  199.   SHORTINT frontColor
  200.   SHORTINT backColor
  201.   LONGINT  potVal
  202.   ADDRESS  nextNode
  203. END STRUCT
  204.  
  205. STRUCT CoordType
  206.   SHORTINT x1
  207.   SHORTINT y1
  208.   SHORTINT x2
  209.   SHORTINT y2
  210.   LONGINT  valid
  211. END STRUCT
  212.  
  213. STRUCT FontInfo
  214.   ADDRESS  fontName
  215.   SHORTINT fontHeight  
  216.   SHORTINT textStyle
  217.   SHORTINT frontColor
  218.   SHORTINT backColor
  219. END STRUCT
  220.  
  221. {*
  222. ** Globals.
  223. *}
  224. LONGINT finished
  225. LONGINT wdwFlags, wdwID, dirty, toolBarActive
  226. SHORTINT wdw_x1, wdw_y1, wdw_x2, wdw_y2
  227. SHORTINT old_wdw_x1, old_wdw_y1
  228. SHORTINT gadCount
  229. STRING wdwTitle SIZE 100
  230. STRING projectName SIZE 80
  231. STRING reqName SIZE 80
  232. DECLARE STRUCT GUIObjType *guiObjList
  233. ADDRESS spriteData
  234. DIM STRING buttonText(maxToolBarButtons) SIZE 15
  235.  
  236. {*
  237. ** Shared library function declarations.
  238. *}
  239. LIBRARY "graphics.library"
  240. DECLARE FUNCTION SetDrMd(ADDRESS RPort, SHORTINT mode) LIBRARY graphics
  241. DECLARE FUNCTION SHORTINT TextLength(ADDRESS RPort, STRING theText, ~
  242.                      SHORTINT count) LIBRARY graphics
  243.  
  244. LIBRARY "intuition.library"
  245. DECLARE FUNCTION SetPointer(ADDRESS wdw,ADDRESS spData,h%,w%,xOff%,yOff%) LIBRARY intuition
  246. DECLARE FUNCTION SetWindowTitles(ADDRESS wdw,wdw_title$,scr_title$) LIBRARY intuition
  247. CONST LEAVE = -1&
  248.  
  249. {*
  250. ** External SUB declarations.
  251. *}
  252. DECLARE SUB LONGINT FontInfoRequest(ADDRESS fontInfoStruct) EXTERNAL
  253.  
  254. '..See external references section in FontReq.b re: the following kludge!
  255. ASSEM 
  256.   xdef _EXIT_PROG
  257. END ASSEM
  258.  
  259. {*
  260. ** Forward SUB references.
  261. *}
  262. DECLARE SUB RedrawGUIObjects
  263. DECLARE SUB ADDRESS GUIObjVal(ADDRESS guiObjAddr, STRING prompt)
  264.  
  265. {*
  266. ** Subprogram definitions.
  267. *}
  268.  
  269. {* General SUBs *}
  270. SUB InitToolBarButtonText
  271. SHARED buttonText
  272. SHORTINT i
  273.   FOR i=1 TO maxToolBarButtons
  274.     READ buttonText(i)
  275.   NEXT
  276.   DATA "Button", "String", "LongInt", "PotX", "PotY", "Text"
  277.   DATA "Plateau", "Panel"
  278. END SUB
  279.  
  280. SUB InitCrossHairPointerData
  281. SHARED spriteData
  282. SHORTINT bytes, i, theWord
  283. CONST numberOfPairs = 17
  284.  
  285.   bytes = numberOfPairs*2*SIZEOF(SHORTINT)
  286.   spriteData = ALLOC(bytes,0)    '..allocate CHIP memory for sprite data.
  287.  
  288.   IF spriteData <> null THEN
  289.     FOR i=0 TO bytes-1 STEP 2
  290.       READ theWord
  291.       *%(spriteData+i) := theWord
  292.     NEXT
  293.  
  294.     DATA 0,0    '..position, control
  295.  
  296.     DATA &H0000, &H0000
  297.     DATA &H0000, &H0000
  298.  
  299.     DATA &H0100, &H0000
  300.     DATA &H0100, &H0000
  301.     DATA &H0100, &H0000
  302.     DATA &H0100, &H0000
  303.  
  304.     DATA &H0000, &H0000
  305.     DATA &HFD7E, &H0000
  306.     DATA &H0000, &H0000
  307.  
  308.     DATA &H0100, &H0000
  309.     DATA &H0100, &H0000
  310.     DATA &H0100, &H0000
  311.     DATA &H0100, &H0000
  312.  
  313.     DATA &H0000, &H0000    
  314.     DATA &H0000, &H0000    
  315.     
  316.     DATA 0,0    '..end
  317.   END IF
  318. END SUB
  319.  
  320. SUB LTRIM$(STRING x)
  321. SHORTINT i
  322.   FOR i=1 TO LEN(x)
  323.     IF MID$(x,i,1) <> " " THEN EXIT FOR 
  324.   NEXT
  325.   LTRIM$ = MID$(x,i)
  326. END SUB
  327.  
  328. SUB SetCurrWdw
  329. SHARED toolBarActive, wdwID
  330. SHORTINT currWdw
  331.   IF NOT toolBarActive THEN 
  332.     WINDOW OUTPUT wdwID
  333.   ELSE
  334.     currWdw = WINDOW(0)
  335.     IF currWdw = wdwID OR currWdw = toolWdw THEN WINDOW OUTPUT currWdw
  336.   END IF
  337. END SUB
  338.  
  339. SUB SetWdwRect
  340. SHARED wdwID, toolBarActive, dirty
  341. SHARED old_wdw_x1, old_wdw_y1
  342. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  343. DECLARE STRUCT WindowStruct *wdw
  344.   WINDOW OUTPUT wdwID
  345.   wdw = WINDOW(7)
  346.   wdw_x1 = wdw->LeftEdge
  347.   wdw_y1 = wdw->TopEdge
  348.   wdw_x2 = wdw_x1 + WINDOW(2)
  349.   wdw_y2 = wdw_y1 + WINDOW(3)
  350.   IF toolBarActive THEN WINDOW OUTPUT toolWdw
  351.   IF wdw_x1 <> old_wdw_x1 OR wdw_y1 <> old_wdw_y1 THEN 
  352.     dirty = true
  353.     old_wdw_x1 = wdw_x1
  354.     old_wdw_y1 = wdw_y1
  355.   END IF
  356. END SUB
  357.  
  358. SUB STRING Rect(SHORTINT x1,SHORTINT y1,SHORTINT x2,SHORTINT y2)
  359.   Rect = "("+LTRIM$(STR$(x1))+","+LTRIM$(STR$(y1))+")-("+ ~
  360.      LTRIM$(STR$(x2))+","+LTRIM$(STR$(y2))+")"
  361. END SUB
  362.  
  363. SUB ShowMouseCoordinates(SHORTINT x1, SHORTINT y1, SHORTINT x2, SHORTINT y2)
  364. SHARED wdwID, wdwFlags, wdwTitle
  365.   WINDOW OUTPUT wdwID
  366.   IF (wdwFlags AND 2) OR (wdwFlags AND 4) OR (wdwFlags AND 8) OR (wdwTitle <> "") THEN 
  367.     SetWindowTitles(WINDOW(7),    "("+LTRIM$(STR$(x1))+","+ ~
  368.                 LTRIM$(STR$(y1))+")-("+ ~
  369.                 LTRIM$(STR$(x2))+","+ ~
  370.                 LTRIM$(STR$(y2))+")", ~
  371.             LEAVE)
  372.   END IF
  373. END SUB
  374.  
  375. SUB ResetReqWdwTitle
  376. SHARED wdwID, wdwFlags, wdwTitle
  377.   WINDOW OUTPUT wdwID
  378.   IF wdwTitle <> "" THEN
  379.     SetWindowTitles(WINDOW(7),wdwTitle,LEAVE)
  380.   ELSE
  381.     IF (wdwFlags AND 2) OR (wdwFlags AND 4) OR (wdwFlags AND 8) THEN
  382.       SetWindowTitles(WINDOW(7),"",LEAVE)
  383.     END IF
  384.   END IF
  385. END SUB
  386.  
  387. SUB CreateWindow
  388. SHARED wdwTitle, wdwFlags, wdwID
  389. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  390. SHARED spriteData
  391.   IF wdwFlags AND 2 THEN
  392.     '..Moveable, so need a title bar.
  393.     WINDOW wdwID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  394.   ELSE
  395.     IF wdwTitle <> "" THEN
  396.       '..A title has been specified.
  397.       WINDOW wdwID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  398.     ELSE
  399.       '..No title specified.
  400.       WINDOW wdwID,,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  401.     END IF
  402.   END IF
  403.  
  404.   '..Set the window's mouse pointer.
  405.   IF spriteData <> null THEN CALL SetPointer(WINDOW(7), spriteData, 15, 15, -8, -7)
  406.  
  407.   '..Redraw gadgets and text.
  408.   RedrawGUIObjects
  409. END SUB
  410.  
  411. SUB SetupMenus
  412. SHARED toolBarActive, wdwFlags
  413. SHORTINT i
  414.   MENU mProject,iProject,sEnable,    "Project"
  415.   MENU mProject,iNew,sEnable,        "   New",    "N"
  416.   MENU mProject,iOpen,sEnable,        "   Open...",    "O"
  417.   MENU mProject,iSave,sEnable,        "   Save...",    "S"
  418.   MENU mProject,iSaveAs,sEnable,    "   Save As..."
  419.   MENU mProject,iToolBar,sEnable,    "   Tool Bar",    "T"
  420.   MENU mProject,iSep1.1,sDisable,    "-----------------"
  421.   MENU mProject,iAbout,sEnable,        "   About..."
  422.   MENU mProject,iQuit,sEnable,        "   Quit",    "Q"
  423.  
  424.   MENU mWindow,iWindow,sEnable,        "Window"
  425.   MENU mWindow,iRedraw,sEnable,        "   Redraw",    "R"
  426.   MENU mWindow,iPreview,sEnable,    "   Preview",    "P"
  427.   MENU mWindow,iSep2.1,sDisable,    "----------------"
  428.   MENU mWindow,iSetId,sEnable,        "   Set Id..."
  429.   MENU mWindow,iSetTitle,sEnable,    "   Set Title..."
  430.   MENU mWindow,iSep2.2,sDisable,    "----------------"
  431.   MENU mWindow,iSizeGadget,sEnable,    "   Size Gadget"
  432.   MENU mWindow,iMoveable,sEnable,    "   Moveable"
  433.   MENU mWindow,iDepthGadget,sEnable,    "   Depth Gadget"
  434.   MENU mWindow,iCloseGadget,sEnable,    "   Close Gadget"
  435.   MENU mWindow,iSmartRefresh,sEnable,    "   Smart Refresh"
  436.   MENU mWindow,iBorderless,sEnable,    "   Borderless"
  437.  
  438.   '..Is the Tool Bar window active?
  439.   IF toolBarActive THEN MENU mProject,iToolBar,sCheck
  440.  
  441.   '..Set window menu checkmarks.
  442.   FOR i=0 TO 5
  443.     IF wdwFlags AND CINT(2^i) THEN MENU mWindow,iSizeGadget+i,sCheck
  444.   NEXT 
  445. END SUB
  446.  
  447. SUB DrawTextLayoutGuide(SHORTINT x1, SHORTINT y1, SHORTINT x2, SHORTINT y2)
  448.   '..Left edge of layout guide 
  449.   '..(possibly adjust, since it may have grown in 
  450.   '..height due to large font being specified while 
  451.   '..near top of window).
  452.   IF y1 < 0 THEN y1 = 0
  453.   LINE (x1,y1)-(x1,y2),2
  454.  
  455.   '..Text length indicator.
  456.   LINE (x1,y2)-(x2,y2),2
  457. END SUB
  458.  
  459. {* GUI Object List related SUBs/FNs *}
  460.  
  461. DEF ADDRESS NewGUIObj = ALLOC(SIZEOF(GUIObjType))
  462.  
  463. SUB ADDRESS GUIObjListHead
  464. SHARED guiObjList
  465.   guiObjList = NewGUIObj
  466.  
  467.   IF guiObjList = null THEN 
  468.     MsgBox "Memory allocation error!","Continue"
  469.   END IF
  470.  
  471.   guiObjList->kind = headOfList
  472.  
  473.   GUIObjListHead = guiObjList
  474. END SUB
  475.  
  476. SUB LONGINT NodesOK(ADDRESS theNode)
  477. SHARED guiObjList
  478.   IF guiObjList = null THEN
  479.     MsgBox "GUI Object List is not initialised!","Continue"
  480.     NodesOK = false
  481.     EXIT SUB
  482.   END IF
  483.   
  484.   IF theNode = null THEN
  485.     MsgBox "GUI Object Node is null!","Continue"
  486.     NodesOK = false
  487.     EXIT SUB
  488.   END IF
  489.  
  490.   NodesOK = true
  491. END SUB
  492.  
  493. SUB LONGINT NodesMatch(ADDRESS a, ADDRESS b)
  494. DECLARE STRUCT GUIObjType *node1, *node2
  495.   node1 = a
  496.   node2 = b
  497.  
  498.   IF node1->kind = node2->kind AND ~
  499.      node1->x1 = node2->x1 AND node1->y1 = node2->y1 AND ~
  500.      node1->x2 = node2->x2 AND node1->y2 = node2->y2 THEN
  501.     '..They are equal.
  502.     NodesMatch = true
  503.   ELSE
  504.     '..They are different.
  505.     NodesMatch = false
  506.   END IF
  507. END SUB
  508.  
  509. SUB AddGUIObj(ADDRESS theNode)
  510. SHARED guiObjList, gadCount
  511. DECLARE STRUCT GUIObjType *curr
  512.   IF NodesOK(theNode) THEN
  513.     '..Seek end of the list.   
  514.     curr = guiObjList
  515.     WHILE curr->nextNode <> null
  516.       curr = curr->nextNode
  517.     WEND
  518.  
  519.     '..Add the new node.
  520.     IF GadCount <= 255 THEN
  521.       IF curr->kind >= buttonGadget AND curr->kind <= potYGadget THEN ++gadCount
  522.       curr->nextNode = theNode
  523.     END IF
  524.   END IF
  525. END SUB
  526.  
  527. SUB RemoveGUIObj(ADDRESS theNode)
  528. SHARED guiObjList, gadCount
  529. DECLARE STRUCT GUIObjType *prev, *curr
  530. LONGINT found
  531.   IF NodesOK(theNode) THEN
  532.     '..Find node.
  533.     prev = guiObjList
  534.     curr = guiObjList->nextNode
  535.     found = false
  536.     WHILE NOT found AND curr <> null
  537.       IF NodesMatch(theNode,curr) THEN 
  538.         found = true
  539.       ELSE
  540.         prev = curr
  541.         curr = curr->nextNode
  542.       END IF
  543.     WEND
  544.  
  545.     '..Remove node from list.
  546.     IF found THEN 
  547.       IF curr->kind >= buttonGadget AND curr->kind <= potYGadget THEN --gadCount
  548.       prev->nextNode = curr->nextNode
  549.     END IF
  550.   END IF
  551. END SUB
  552.  
  553. SUB RedrawGUIObjects
  554. SHARED guiObjList
  555. DECLARE STRUCT GUIObjType *curr
  556.   IF guiObjList = null THEN
  557.     MsgBox "GUI Object List is not initialised!","Continue"
  558.   ELSE
  559.     '..Traverse the list drawing objects in requester window.
  560.     curr = guiObjList->nextNode
  561.     WHILE curr <> null
  562.       objKind = curr->kind
  563.       IF objKind = staticText THEN
  564.     '..Text.
  565.     DrawTextLayoutGuide(curr->x1,curr->y1,curr->x2,curr->y2)
  566.       ELSE
  567.     '..Gadget or Bevel-Box.
  568.         CASE
  569.           objKind = buttonGadget     : boxStyle = RAISED
  570.           objKind = stringGadget     : boxStyle = STRGAD
  571.           objKind = longintGadget    : boxStyle = STRGAD
  572.           objKind = potXGadget       : boxStyle = RAISED
  573.           objKind = potYGadget       : boxStyle = RAISED
  574.       objKind = raisedBevelBox   : boxStyle = RAISED
  575.       objKind = recessedBevelBox : boxStyle = RECESSED
  576.         END CASE
  577.  
  578.     BEVELBOX (curr->x1,curr->y1)-(curr->x2,curr->y2),boxStyle
  579.       END IF
  580.  
  581.       curr = curr->nextNode
  582.     WEND
  583.   END IF
  584. END SUB
  585.  
  586. SUB SaveGUIObjects(SHORTINT fileNum)
  587. SHARED guiObjList
  588. DECLARE STRUCT GUIObjType *curr
  589.   IF guiObjList = null THEN
  590.     MsgBox "GUI Object List is not initialised!","Continue"
  591.   ELSE
  592.     '..Traverse the list writing objects to a file.   
  593.     curr = guiObjList->nextNode
  594.     WHILE curr <> null
  595.       WRITE #fileNum,curr->kind
  596.       IF curr->kind = potXGadget OR curr->kind = potYGadget THEN
  597.     WRITE #fileNum,curr->potVal
  598.       ELSE
  599.     IF curr->kind <> raisedBevelBox AND curr->kind <> recessedBevelBox THEN
  600.       WRITE #fileNum,CSTR(curr->theText)
  601.     END IF
  602.       END IF
  603.       IF curr->kind = staticText THEN
  604.     WRITE #fileNum,CSTR(curr->fontName)
  605.     WRITE #fileNum,curr->fontHeight
  606.     WRITE #fileNum,curr->textStyle
  607.     WRITE #fileNum,curr->frontColor
  608.     WRITE #fileNum,curr->backColor
  609.       END IF
  610.       WRITE #fileNum,curr->x1,curr->y1,curr->x2,curr->y2
  611.       curr = curr->nextNode
  612.     WEND
  613.   END IF
  614. END SUB
  615.  
  616. SUB GetGUIObjects(SHORTINT fileNum)
  617. SHARED guiObjList, gadCount
  618. DECLARE STRUCT GUIObjType *curr
  619. SHORTINT x1,y1,x2,y2
  620.   IF guiObjList = null THEN
  621.     MsgBox "GUI Object List is not initialised!","Continue"
  622.   ELSE
  623.     '..Read objects from a file adding them to the list.
  624.     gadCount = 0
  625.     curr = guiObjList
  626.     WHILE NOT EOF(fileNum)
  627.       curr->nextNode = NewGUIObj
  628.       curr = curr->nextNode
  629.       IF curr = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  630.       INPUT #fileNum,theVal : curr->kind = theVal
  631.       IF curr->kind <> staticText AND curr->kind <> raisedBevelBox AND ~
  632.      curr->kind <> recessedBevelBox THEN ++gadCount
  633.       IF curr->kind = potXGadget OR curr->kind = potYGadget THEN
  634.     INPUT #fileNum,theVal : curr->potVal = theVal
  635.       ELSE
  636.     IF curr->kind <> raisedBevelBox AND curr->kind <> recessedBevelBox THEN
  637.       INPUT #fileNum,theVal$
  638.           curr->theText = ALLOC(LEN(theVal$)+1)
  639.           IF curr->theText = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  640.           STRING theText ADDRESS curr->theText
  641.           theText = theVal$
  642.     END IF
  643.       END IF
  644.       IF curr->kind = staticText THEN
  645.     INPUT #fileNum,theVal$
  646.         curr->fontName = ALLOC(LEN(theVal$)+1)
  647.         IF curr->fontName = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  648.         STRING fontName ADDRESS curr->fontName
  649.         fontName = theVal$
  650.     INPUT #fileNum,theVal : curr->fontHeight = theVal
  651.     INPUT #fileNum,theVal : curr->textStyle = theVal
  652.     INPUT #fileNum,theVal : curr->frontColor = theVal
  653.     INPUT #fileNum,theVal : curr->backColor = theVal
  654.       END IF 
  655.       INPUT #fileNum,x1,y1,x2,y2
  656.       curr->x1 = x1 : curr->y1 = y1 : curr->x2 = x2 : curr->y2 = y2
  657.     WEND
  658.   END IF
  659. END SUB
  660.  
  661. SUB SHORTINT RenderGUIObjects(SHORTINT fileNum)
  662. SHARED guiObjList
  663. DECLARE STRUCT GUIObjType *curr
  664. LONGINT theGadNum
  665. SHORTINT x1,y1, x2,y2
  666. SHORTINT bevelBoxMode
  667.   IF guiObjList = null THEN
  668.     MsgBox "GUI Object List is not initialised!","Continue"
  669.     '..No minimum gadget number.
  670.     RenderGUIObjects = 0
  671.   ELSE
  672.     '..Traverse the list generating code to render objects.
  673.     theGadNum = 256
  674.     curr = guiObjList->nextNode
  675.     WHILE curr <> null
  676.       IF curr->kind = staticText THEN
  677.     '..Text.
  678.     PRINT #fileNum,"  FONT ";CHR$(34);CSTR(curr->fontName);CHR$(34);","; ~
  679.                    LTRIM$(STR$(curr->fontHeight));" : ";
  680.     PRINT #fileNum,"STYLE";curr->textStyle;" : ";
  681.     PRINT #fileNum,"COLOR";STR$(curr->frontColor);","; ~
  682.             LTRIM$(STR$(curr->backColor));" : ";
  683.         PRINT #fileNum,"PENUP";" : ";
  684.     IF CSTR(curr->theText) <> "" THEN
  685.       PRINT #fileNum,"SETXY";STR$(curr->x1);",";LTRIM$(STR$(curr->y2))
  686.       PRINT #fileNum,"  PRINT ";CHR$(34);CSTR(curr->theText);CHR$(34);";"
  687.     END IF
  688.       ELSE
  689.     objKind = curr->kind
  690.        IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  691.       '..Bevel-Box.
  692.       PRINT #fileNum,"  BEVELBOX ";Rect(curr->x1,curr->y1,curr->x2,curr->y2);",";
  693.       IF objKind = raisedBevelBox THEN 
  694.         bevelBoxMode = RAISED 
  695.       ELSE
  696.         bevelBoxMode = RECESSED
  697.       END IF
  698.       PRINT #fileNum,LTRIM$(STR$(bevelBoxMode))
  699.     ELSE
  700.       '..Gadget.
  701.       x1 = curr->x1 : y1 = curr->y1
  702.       x2 = curr->x2 : y2 = curr->y2
  703.       
  704.           objKind = curr->kind
  705.         
  706.       '..Are offsets required for this gadget?
  707.       IF objKind = buttonGadget THEN
  708.         ++x2
  709.         ++y2
  710.       ELSE
  711.         IF objKind = stringGadget OR objKind = longintGadget THEN
  712.           x1 = x1+6 : y1 = y1+3
  713.           x2 = x2+6 : y2 = y2+3
  714.         END IF
  715.       END IF
  716.  
  717.           --theGadNum
  718.  
  719.        PRINT #fileNum,"  GADGET";STR$(theGadNum);",ON,";
  720.       IF curr->kind <> potXGadget AND curr->kind <> potYGadget THEN
  721.         PRINT #fileNum,CHR$(34);
  722.         IF CSTR(curr->theText) <> "" THEN PRINT #fileNum,CSTR(curr->theText);
  723.           PRINT #fileNum,CHR$(34);",";
  724.         ELSE
  725.           PRINT #fileNum,LTRIM$(STR$(curr->potVal));",";
  726.       END IF
  727.       PRINT #fileNum,Rect(x1,y1,x2,y2);",";
  728.           CASE
  729.             curr->kind = buttonGadget  : PRINT #fileNum,"BUTTON"
  730.             curr->kind = stringGadget  : PRINT #fileNum,"STRING"
  731.             curr->kind = longintGadget : PRINT #fileNum,"LONGINT"
  732.             curr->kind = potXGadget    : PRINT #fileNum,"POTX"
  733.             curr->kind = potYGadget    : PRINT #fileNum,"POTY"
  734.           END CASE
  735.     END IF
  736.       END IF
  737.       curr = curr->nextNode
  738.     WEND
  739.     '..Return minimum gadget number or zero if no gadgets.
  740.     IF theGadNum <> 256 THEN RenderGUIObjects = theGadNum ELSE RenderGUIObjects = 0
  741.   END IF
  742. END SUB
  743.  
  744. {* GUI object modification SUBs *}
  745.  
  746. SUB ADDRESS InsideGUIObj(SHORTINT x, SHORTINT y)
  747. SHARED guiObjList
  748. DECLARE STRUCT GUIObjType *curr
  749. LONGINT withinBounds
  750.   IF guiObjList = null THEN
  751.     MsgBox "GUI Object List is not initialised!","Continue"
  752.     InsideGUIObj = null
  753.   ELSE
  754.     '..Find node.
  755.     curr = guiObjList->nextNode
  756.     withinBounds = false
  757.     WHILE NOT withinBounds AND curr <> null
  758.       IF x > curr->x1+EDGE_THICKNESS AND x < curr->x2-EDGE_THICKNESS AND ~ 
  759.      y > curr->y1+EDGE_THICKNESS AND y < curr->y2-EDGE_THICKNESS THEN
  760.         withinBounds = true
  761.       ELSE
  762.         curr = curr->nextNode
  763.       END IF
  764.     WEND
  765.  
  766.     '..Return address of node (or null).
  767.     IF withinBounds THEN InsideGUIObj = curr ELSE InsideGUIObj = null
  768.   END IF
  769. END SUB
  770.  
  771. SUB SelectGUIObj(ADDRESS theObject)
  772. SHARED wdwID
  773. DECLARE STRUCT GUIObjType *guiObject
  774. SHORTINT left, right, top, bottom
  775.   guiObject = theObject
  776.   left = guiObject->x1 : top = guiObject->y1
  777.   right = guiObject->x2 : bottom = guiObject->y2
  778.   WINDOW OUTPUT wdwID
  779.   COLOR 3:PENUP:SETXY left,top:PENDOWN
  780.   SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  781. END SUB
  782.  
  783. SUB DeleteGUIObj(ADDRESS theObject)
  784. SHARED wdwID, dirty
  785. DECLARE STRUCT GUIObjType *guiObject
  786. STRING objName SIZE 20
  787.   guiObject = theObject
  788.   objKind = guiObject->kind
  789.   CASE
  790.     objKind = buttonGadget     : objName = "button"  
  791.     objKind = stringGadget     : objName = "string gadget"
  792.     objKind = longintGadget    : objName = "longint gadget"  
  793.     objKind = potXGadget       : objName = "horizontal slider"  
  794.     objKind = potYGadget       : objName = "vertical slider"  
  795.     objKind = staticText       : objName = "static text"
  796.     objKind = raisedBevelBox   : objName = "plateau"
  797.     objKind = recessedBevelBox : objName = "panel"
  798.   END CASE
  799.   IF MsgBox("Delete selected "+objName+"?","Yes","No") THEN 
  800.     RemoveGUIObj(theObject)
  801.     IF NOT dirty THEN dirty = true
  802.   END IF
  803.   '..Refresh display to get rid of selection box and
  804.   '..possibly to reflect absence of deleted object.
  805.   WINDOW OUTPUT wdwID
  806.   CLS : RedrawGUIObjects
  807. END SUB
  808.  
  809. SUB ModifyGUIObjVal(ADDRESS theObject)
  810. SHARED dirty, wdwID
  811. DECLARE STRUCT GUIObjType *guiObject, tmpObject
  812. STRING objName SIZE 20
  813. STRING prompt SIZE 30
  814.  
  815.   guiObject = theObject
  816.  
  817.   objKind = guiObject->kind
  818.  
  819.   '..Can't modify Bevel-Box since it holds no text value!
  820.   IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN 
  821.     MsgBox "No text to modify.","Continue"
  822.     '..Refresh display to get rid of selection box.
  823.     WINDOW OUTPUT wdwID
  824.     CLS : RedrawGUIObjects
  825.     EXIT SUB
  826.   END IF
  827.  
  828.   CASE
  829.    objKind = buttonGadget : objName="button" : prompt = "Enter Button Text"
  830.    objKind = stringGadget : objName="string gadget" : prompt = "Enter Default Text"
  831.    objKind = longintGadget : objName="longint gadget" : prompt = "Enter Default Value"  
  832.    objKind = potXGadget : objName="horizontal slider":prompt = "Enter Maximum Slider Value"
  833.    objKind = potYGadget : objName="vertical slider":prompt = "Enter Maximum Slider Value" 
  834.    objKind = staticText : objName="static text":prompt = "Enter Static Text"  
  835.   END CASE
  836.  
  837.   '..Store current values.
  838.   IF objKind <> potXGadget AND objKind <> potYGadget THEN 
  839.     tmpObject->theText = guiObject->theText
  840.   END IF
  841.  
  842.   IF objKind = staticText THEN
  843.     tmpObject->fontName = guiObject->fontName
  844.     tmpObject->fontHeight = guiObject->fontHeight
  845.     tmpObject->textStyle = guiObject->textStyle
  846.     tmpObject->frontColor = guiObject->frontColor
  847.     tmpObject->backColor = guiObject->backColor
  848.   END IF
  849.  
  850.   IF objKind = potXGadget OR objKind = potYGadget THEN
  851.     tmpObject->potVal = guiObject->potVal
  852.   END IF
  853.  
  854.   '..Change the GUI object?
  855.   IF MsgBox("Modify selected "+objName+"?","Yes","No") THEN 
  856.     IF GUIObjVal(theObject, prompt) <> null THEN 
  857.       '..Valid change made.     
  858.       IF NOT dirty THEN dirty = true
  859.     ELSE
  860.       '..Invalid value(s) entered, so restore old values.
  861.       IF objKind <> potXGadget AND objKind <> potYGadget THEN 
  862.          guiObject->theText = tmpObject->theText
  863.       END IF
  864.  
  865.       IF objKind = staticText THEN
  866.         guiObject->fontName = tmpObject->fontName
  867.         guiObject->fontHeight = tmpObject->fontHeight
  868.         guiObject->textStyle = tmpObject->textStyle
  869.         guiObject->frontColor = tmpObject->frontColor
  870.         guiObject->backColor = tmpObject->backColor
  871.       END IF
  872.  
  873.      IF objKind = potXGadget OR objKind = potYGadget THEN
  874.         guiObject->potVal = tmpObject->potVal
  875.      END IF
  876.     END IF
  877.   END IF
  878.   '..Refresh display to get rid of selection box.
  879.   WINDOW OUTPUT wdwID
  880.   CLS : RedrawGUIObjects
  881. END SUB
  882.  
  883. SUB MoveGUIObj(ADDRESS theObject)
  884. SHARED wdwID, dirty
  885. DECLARE STRUCT GUIObjType *guiObject
  886. ADDRESS RPort
  887. SHORTINT oldX1,oldY1, oldX2,oldY2
  888. SHORTINT x,y, lastX,lastY, xDiff,yDiff
  889. SHORTINT left, right, top, bottom
  890.  
  891.   guiObject = theObject
  892.  
  893.   '..Remove the object from the list.
  894.   RemoveGUIObj(guiObject)
  895.  
  896.   '..Refresh the display to show absence of the object.
  897.   WINDOW OUTPUT wdwID
  898.   CLS : RedrawGUIObjects
  899.   
  900.   '..Get initial position of object.
  901.   left = guiObject->x1 : top = guiObject->y1
  902.   right = guiObject->x2 : bottom = guiObject->y2
  903.  
  904.   oldX1 = left : oldY1 = top
  905.   oldX2 = right : oldY2 = bottom
  906.  
  907.   RPort = WINDOW(8)
  908.   SetDrMd(RPort,2)    '..XOR mode
  909.  
  910.   selected = true
  911.  
  912.   lastX = MOUSE(1) : lastY = MOUSE(2)
  913.   x = lastX : y = lastY
  914.  
  915.   '..Allow the object to be moved.
  916.   WHILE selected AND ~
  917.     lastX > left+EDGE_THICKNESS AND lastX < right-EDGE_THICKNESS AND ~
  918.     lastY > top+EDGE_THICKNESS AND lastY < bottom-EDGE_THICKNESS
  919.     IF MOUSE(0) THEN
  920.       '..Draw selection box.
  921.       COLOR 1:PENUP:SETXY left,top:PENDOWN
  922.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  923.  
  924.       ShowMouseCoordinates(left,top,right,bottom)
  925.  
  926.       '..Wait for mouse position to change or left button to be released.
  927.       WHILE selected AND x = lastX AND y = lastY
  928.         x = MOUSE(1) : y = MOUSE(2)
  929.         IF NOT MOUSE(0) THEN selected = false
  930.       WEND
  931.  
  932.       '..Erase selection box.
  933.       COLOR 0:PENUP:SETXY left,top:PENDOWN
  934.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  935.  
  936.       '..Adjust selection box? 
  937.       '..Treat horizontal and vertical motion independently.
  938.       xDiff = x-lastX : yDiff = y-lastY
  939.  
  940.       IF left+xDiff >= 0 THEN
  941.         left = left + xDiff : right = right + xDiff
  942.     lastX = x
  943.       ELSE
  944.     x = lastX
  945.       END IF
  946.  
  947.       IF top+yDiff >= 0 THEN
  948.         top = top + yDiff : bottom = bottom + yDiff 
  949.     lastY = y
  950.       ELSE
  951.     y = lastY
  952.       END IF
  953.     ELSE
  954.       '..Mouse button has been released.
  955.       selected = false
  956.     END IF 
  957.   WEND
  958.    
  959.   SetDrMd(RPort,1)    '..JAM2 mode
  960.   
  961.   '..Modify the object's position.
  962.   guiObject->x1 = left : guiObject->y1 = top
  963.   guiObject->x2 = right : guiObject->y2 = bottom
  964.  
  965.   '..Add the modified object to (the end of) the list.
  966.   guiObject->nextNode = null
  967.   AddGUIObj(guiObject)
  968.  
  969.   '..Refresh the display to show object's (new) position.
  970.   WINDOW OUTPUT wdwID
  971.   CLS : RedrawGUIObjects
  972.  
  973.   IF NOT dirty AND (left <> oldX1 OR right <> oldX2 OR ~
  974.           top <> oldY1 OR bottom <> oldY2) THEN dirty = true
  975.  
  976.   ResetReqWdwTitle
  977. END SUB
  978.  
  979. SUB SHORTINT ObjEdge(SHORTINT x, SHORTINT y, ADDRESS theObject)
  980. DECLARE STRUCT GUIObjType *guiObject
  981.   guiObject = theObject
  982.  
  983.   CASE
  984.     x >= guiObject->x1 AND x <= guiObject->x1+EDGE_THICKNESS AND ~
  985.     y >= guiObject->y1 AND y <= guiObject->y2 : ObjEdge = LEFT_EDGE
  986.  
  987.     x >= guiObject->x2-EDGE_THICKNESS AND x <= guiObject->x2 AND ~
  988.     y >= guiObject->y1 AND y <= guiObject->y2: ObjEdge = RIGHT_EDGE
  989.  
  990.     y >= guiObject->y1 AND y <= guiObject->y1+EDGE_THICKNESS AND ~
  991.     x >= guiObject->x1 AND x <= guiObject->x2 : ObjEdge = TOP_EDGE
  992.  
  993.     y >= guiObject->y2-EDGE_THICKNESS AND y <= guiObject->y2 AND ~
  994.     x >= guiObject->x1 AND x <= guiObject->x2: ObjEdge = BOTTOM_EDGE
  995.  
  996.     default : ObjEdge = NO_EDGE
  997.   END CASE
  998. END SUB
  999.  
  1000. SUB ADDRESS OnGUIObjBorder(SHORTINT x, SHORTINT y, ADDRESS edge)
  1001. SHARED guiObjList
  1002. DECLARE STRUCT GUIObjType *curr
  1003. LONGINT onBorder
  1004.   IF guiObjList = null THEN
  1005.     MsgBox "GUI Object List is not initialised!","Continue"
  1006.     OnGUIObjBorder = null
  1007.     *%edge := NO_EDGE
  1008.   ELSE
  1009.     '..Find node.
  1010.     curr = guiObjList->nextNode
  1011.     onBorder = false
  1012.     WHILE NOT onBorder AND curr <> null
  1013.       *%edge := ObjEdge(x,y,curr)
  1014.       IF *%edge <> NO_EDGE THEN
  1015.     onBorder = true
  1016.       ELSE
  1017.         curr = curr->nextNode
  1018.       END IF
  1019.     WEND
  1020.  
  1021.     '..Return address of node (or null).
  1022.     IF onBorder THEN 
  1023.       OnGUIObjBorder = curr
  1024.     ELSE 
  1025.       *%edge := NO_EDGE
  1026.       OnGUIObjBorder = null
  1027.     END IF
  1028.   END IF
  1029. END SUB
  1030.  
  1031. SUB ResizeGUIObj(ADDRESS theObject, SHORTINT edge)
  1032. SHARED wdwID, dirty
  1033. DECLARE STRUCT GUIObjType *guiObject
  1034. ADDRESS RPort
  1035. SHORTINT oldX1,oldY1, oldX2,oldY2
  1036. SHORTINT x,y, lastX,lastY
  1037. SHORTINT left, right, top, bottom
  1038.  
  1039.   guiObject = theObject
  1040.  
  1041.   IF guiObject->kind = staticText THEN EXIT SUB
  1042.  
  1043.   '..Remove the object from the list.
  1044.   RemoveGUIObj(guiObject)
  1045.  
  1046.   '..Refresh the display to show absence of the object.
  1047.   WINDOW OUTPUT wdwID
  1048.   CLS : RedrawGUIObjects
  1049.   
  1050.   '..Get initial position of object.
  1051.   left = guiObject->x1 : top = guiObject->y1
  1052.   right = guiObject->x2 : bottom = guiObject->y2
  1053.  
  1054.   oldX1 = left : oldY1 = top
  1055.   oldX2 = right : oldY2 = bottom
  1056.  
  1057.   RPort = WINDOW(8)
  1058.   SetDrMd(RPort,2)    '..XOR mode
  1059.  
  1060.   selected = true
  1061.  
  1062.   lastX = MOUSE(1) : lastY = MOUSE(2)
  1063.   x = lastX : y = lastY
  1064.  
  1065.   '..Allow the object to be resized.
  1066.   WHILE selected
  1067.     IF MOUSE(0) THEN
  1068.       '..Draw selection box.
  1069.       COLOR 1:PENUP:SETXY left,top:PENDOWN
  1070.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  1071.  
  1072.       ShowMouseCoordinates(left,top,right,bottom)
  1073.  
  1074.       '..Wait for mouse position to change or left button to be released.
  1075.       WHILE selected AND x = lastX AND y = lastY
  1076.         x = MOUSE(1) : y = MOUSE(2)
  1077.         IF NOT MOUSE(0) THEN selected = false
  1078.       WEND
  1079.  
  1080.       '..Erase selection box.
  1081.       COLOR 0:PENUP:SETXY left,top:PENDOWN
  1082.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  1083.  
  1084.       '..Adjust one edge of the selection box?
  1085.       IF x >= 0 AND y >= 0 THEN
  1086.     '..Yes.
  1087.         CASE
  1088.       edge = LEFT_EDGE   : IF x < right-EDGE_THICKNESS THEN left = x
  1089.       edge = RIGHT_EDGE  : IF x > left+EDGE_THICKNESS THEN right = x
  1090.       edge = TOP_EDGE    : IF y < bottom-EDGE_THICKNESS THEN top = y
  1091.       edge = BOTTOM_EDGE : IF y > top+EDGE_THICKNESS THEN bottom = y
  1092.         END CASE     
  1093.         lastX = x : lastY = y
  1094.       ELSE
  1095.     '..No. Retain previous edge position.
  1096.     x = lastX : y = lastY
  1097.       END IF
  1098.     ELSE
  1099.       '..Mouse button has been released.
  1100.       selected = false
  1101.     END IF 
  1102.   WEND
  1103.    
  1104.   SetDrMd(RPort,1)    '..JAM2 mode
  1105.   
  1106.   '..Modify the object's position.
  1107.   guiObject->x1 = left : guiObject->y1 = top
  1108.   guiObject->x2 = right : guiObject->y2 = bottom
  1109.  
  1110.   '..Add the modified object to (the end of) the list.
  1111.   guiObject->nextNode = null
  1112.   AddGUIObj(guiObject)
  1113.  
  1114.   '..Refresh the display to show object's (new) position.
  1115.   WINDOW OUTPUT wdwID
  1116.   CLS : RedrawGUIObjects
  1117.  
  1118.   IF NOT dirty AND (left <> oldX1 OR right <> oldX2 OR ~
  1119.           top <> oldY1 OR bottom <> oldY2) THEN dirty = true
  1120.  
  1121.   ResetReqWdwTitle
  1122. END SUB
  1123.  
  1124. {* Project menu SUBs *}
  1125.  
  1126. SUB ToggleToolBar
  1127. SHARED toolBarActive, wdwID, buttonText
  1128. SHORTINT fontWidth, fontHeight, n
  1129.  
  1130.   IF NOT toolBarActive THEN
  1131.     '..Activate Tool Bar.
  1132.     fontWidth = SCREEN(5)
  1133.     fontHeight = SCREEN(6)
  1134.     WINDOW toolWdw,,(10,10)-(10+11*fontWidth,10+19.5*fontHeight),10
  1135.     FOR n=gButton TO gRecessedBox
  1136.       '..Render tool bar buttons making each one as wide as necessary
  1137.       '..to accomodate the longest button text.
  1138.       GADGET n,ON,buttonText(n-gButton+1),(fontWidth,fontHeight+(n-1)*2*fontHeight)- ~
  1139.                 (fontWidth+8*fontWidth,fontHeight+n*2*fontHeight),BUTTON,1
  1140.     NEXT
  1141.  
  1142.     WINDOW OUTPUT wdwID
  1143.     MENU mProject,iToolBar,sCheck
  1144.     toolBarActive = true
  1145.   ELSE
  1146.     '..Deactivate Tool Bar.
  1147.     FOR n=gButton TO gRecessedBox
  1148.       GADGET CLOSE n
  1149.     NEXT
  1150.     WINDOW OUTPUT toolWdw    '..prevent main window menus from being cleared.
  1151.     WINDOW CLOSE toolWdw
  1152.     WINDOW OUTPUT wdwID
  1153.     MENU mProject,iToolBar,sEnable
  1154.     toolBarActive = false
  1155.   END IF
  1156. END SUB
  1157.  
  1158. SUB SetProjectName(STRING fileReqTitle)
  1159. SHARED projectName
  1160. STRING newProjectName SIZE 80
  1161.   newProjectName = FileBox$(fileReqTitle)
  1162.   IF newProjectName <> "" THEN projectName = newProjectName
  1163. END SUB
  1164.  
  1165. SUB StoreInfo
  1166. SHARED projectName, reqName
  1167. SHARED wdwID, wdwTitle, wdwFlags
  1168. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1169.   OPEN "O",#1,projectName+".req"
  1170.   IF HANDLE(1) = null THEN 
  1171.     MsgBox "Unable to open "+projectName+".req for writing.","Continue"
  1172.     EXIT SUB
  1173.   ELSE
  1174.     PRINT #1,"#REQED PROJECT#"
  1175.     PRINT #1,reqName
  1176.     WRITE #1,wdwID
  1177.     IF wdwTitle <> "" THEN PRINT #1,wdwTitle ELSE PRINT #1,"#NULL#"
  1178.     WRITE #1,wdwFlags
  1179.     WRITE #1,wdw_x1,wdw_y1,wdw_x2,wdw_y2
  1180.     SaveGUIObjects(1)
  1181.     CLOSE #1
  1182.   END IF
  1183. END SUB
  1184.  
  1185. SUB GenerateCode
  1186. SHARED projectName, reqName, wdwID, wdwTitle, wdwFlags
  1187. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1188. STRING theTitle SIZE 80
  1189. SHORTINT minGadget
  1190.   IF reqName = "" THEN
  1191.     reqName = InputBox$("Requester SUB name?","Set requester SUB name",reqName,170,10)
  1192.   END IF
  1193.  
  1194.   IF reqName = "" THEN
  1195.     MsgBox projectName+".b not created.","Continue"
  1196.     EXIT SUB
  1197.   END IF
  1198.   OPEN "O",#1,projectName+".b"  
  1199.   IF HANDLE(1) = null THEN 
  1200.     MsgBox "Unable to open "+projectName+".b for writing.","Continue"
  1201.     EXIT SUB
  1202.   ELSE
  1203.     PRINT #1,"SUB ";reqName  
  1204.     {* Variables *}
  1205.     PRINT #1,"SHORTINT theGadget, n"  
  1206.     {* Code for window *}
  1207.     PRINT #1,"  WINDOW";STR$(wdwID);",";
  1208.     IF wdwTitle <> "" THEN
  1209.       '..A title has been specified. 
  1210.       PRINT #1,CHR$(34);wdwTitle;CHR$(34);
  1211.     ELSE
  1212.       '..There's no title but the window is moveable
  1213.       '..(otherwise we want no title bar at all).
  1214.       IF wdwFlags AND 2 THEN PRINT #1,CHR$(34);CHR$(34);
  1215.     END IF
  1216.     PRINT #1,",";Rect(wdw_x1,wdw_y1,wdw_x2,wdw_y2);",";LTRIM$(STR$(wdwFlags))
  1217.     {* Render gadgets, bevel-boxes and text *}
  1218.     PRINT #1,"  ";CHR$(123);"* RENDER GADGETS, BEVEL-BOXES AND TEXT *";CHR$(125)
  1219.     minGadget = RenderGUIObjects(1)
  1220.     {* Await and handle gadget activity *}
  1221.     PRINT #1,"  ";CHR$(123);"* GADGET HANDLING CODE STARTS HERE *";CHR$(125)
  1222.     PRINT #1,"  GADGET WAIT 0"
  1223.     PRINT #1,"  theGadget = GADGET(1)"
  1224.     {* Cleanup code *}
  1225.     PRINT #1,"  ";CHR$(123);"* CLEAN UP *";CHR$(125)
  1226.     IF minGadget <> 0 THEN
  1227.       PRINT #1,"  FOR n=255 TO";minGadget;"STEP -1"
  1228.       PRINT #1,"    GADGET CLOSE n"
  1229.       PRINT #1,"  NEXT" 
  1230.     END IF
  1231.     PRINT #1,"  WINDOW CLOSE";wdwID
  1232.     PRINT #1,"END SUB"
  1233.   END IF
  1234.   CLOSE #1
  1235. END SUB
  1236.  
  1237. SUB SaveProject
  1238. SHARED dirty, projectName, reqName
  1239.   SetWdwRect
  1240.   IF dirty THEN
  1241.     IF projectName = "" THEN CALL SetProjectName("Save Project")
  1242.     IF projectName = "" THEN
  1243.       '..Abort.
  1244.       MsgBox "Project name not specified.","Continue"
  1245.     ELSE
  1246.       GenerateCode
  1247.       IF reqName <> "" THEN
  1248.     '..Abort.
  1249.         StoreInfo
  1250.         dirty = false
  1251.       END IF
  1252.     END IF
  1253.   END IF
  1254. END SUB
  1255.  
  1256. SUB SaveAs
  1257. SHARED projectName, reqName, dirty
  1258. STRING oldProjectName SIZE 80
  1259. STRING oldReqName SIZE 80
  1260.   oldProjectName = projectName
  1261.   projectName = ""
  1262.   SetProjectName("Save As...")
  1263.   IF projectName = "" THEN
  1264.     '..Abort.
  1265.     MsgBox "Name not specified.","Continue"
  1266.     projectName = oldProjectName
  1267.   ELSE
  1268.     SetWdwRect
  1269.     oldReqName = reqName
  1270.     reqName = ""
  1271.     GenerateCode
  1272.     IF reqName = "" THEN
  1273.       '..Abort.
  1274.       reqName = oldReqName
  1275.       projectName = oldProjectName
  1276.     ELSE
  1277.       StoreInfo
  1278.       IF dirty THEN dirty = false
  1279.     END IF
  1280.   END IF
  1281. END SUB
  1282.  
  1283. SUB CloseProject
  1284. SHARED wdwID
  1285.   MENU CLEAR
  1286.   WINDOW CLOSE wdwID
  1287. END SUB
  1288.  
  1289. SUB OpenProject
  1290. SHARED projectName, reqName, dirty
  1291. SHARED wdwID, wdwTitle, wdwFlags
  1292. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1293. SHARED old_wdw_x1, old_wdw_y1
  1294. STRING oldProjectName SIZE 80
  1295. STRING fileType SIZE 80
  1296. STRING theName SIZE 80
  1297.  
  1298.   IF dirty THEN
  1299.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1300.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1301.   END IF
  1302.  
  1303.   oldProjectName = projectName
  1304.   SetProjectName("Open Project")
  1305.  
  1306.   IF projectName = "" THEN
  1307.     MsgBox "Project name not specified.","Continue"
  1308.     projectName = oldProjectName
  1309.     EXIT SUB
  1310.   END IF 
  1311.  
  1312.   IF INSTR(projectName,".req") = 0 THEN
  1313.     MsgBox projectName+" not of required type.","Continue"
  1314.     projectName = oldProjectName
  1315.     EXIT SUB
  1316.   END IF
  1317.  
  1318.   IF GUIObjListHead = null THEN
  1319.     projectName = oldProjectName
  1320.     EXIT SUB
  1321.   END IF
  1322.  
  1323.   OPEN "I",#1,projectName
  1324.   IF HANDLE(1) = null THEN
  1325.     MsgBox "Unable to open "+projectName+" for input.","Continue"
  1326.     projectName = oldProjectName
  1327.     EXIT SUB
  1328.   ELSE
  1329.     LINE INPUT #1,fileType
  1330.     IF fileType <> "#REQED PROJECT#" THEN
  1331.       MsgBox projectName+" not of required type.","Continue"
  1332.       projectName = oldProjectName
  1333.       CLOSE #1
  1334.       EXIT SUB
  1335.     END IF
  1336.     CloseProject
  1337.     LINE INPUT #1,reqName
  1338.     INPUT #1,wdwID
  1339.     LINE INPUT #1,wdwTitle : IF wdwTitle = "#NULL#" THEN wdwTitle = ""
  1340.     INPUT #1,wdwFlags
  1341.     INPUT #1,wdw_x1,wdw_y1,wdw_x2,wdw_y2
  1342.     old_wdw_x1 = wdw_x1 : old_wdw_y1 = wdw_y1
  1343.     GetGUIObjects(1)
  1344.     CLOSE #1
  1345.     projectName = LEFT$(projectName,INSTR(projectName,".req")-1)
  1346.   END IF
  1347.   CreateWindow
  1348.   SetupMenus  
  1349.   dirty = false
  1350. END SUB
  1351.  
  1352. SUB NewProject
  1353. SHARED dirty, wdwID, wdwTitle, gadCount
  1354. SHARED wdwFlags, projectName, reqName
  1355. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1356. SHARED old_wdw_x1, old_wdw_y1
  1357. STRING theName SIZE 80
  1358.   IF dirty THEN
  1359.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1360.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1361.   END IF
  1362.   CloseProject
  1363.   IF GUIObjListHead = null THEN EXIT SUB
  1364.   wdwID = 9
  1365.   wdwFlags = 0
  1366.   wdwTitle = ""
  1367.   reqName = ""
  1368.   projectName = ""
  1369.   wdw_x1 = 170 : wdw_y1 = 50 : old_wdw_x1 = 0 : old_wdw_y1 = 0
  1370.   wdw_x2 = 470 : wdw_y2 = 175
  1371.   gadCount = 0
  1372.   CreateWindow
  1373.   SetUpMenus  
  1374.   dirty = false
  1375. END SUB
  1376.  
  1377. SUB QuitProgram
  1378. SHARED finished, dirty, projectName
  1379. STRING theName SIZE 80
  1380.   IF dirty THEN
  1381.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1382.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1383.   END IF
  1384.   finished = true
  1385. END SUB
  1386.  
  1387. {* Window menu SUBs *}
  1388.  
  1389. SUB PreviewRequester
  1390. SHARED wdwID, wdwFlags, wdwTitle
  1391. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1392. SHARED guiObjList
  1393. DECLARE STRUCT GUIObjType *curr
  1394. SHORTINT x1,y1, x2,y2
  1395. SHORTINT ID
  1396. SHORTINT objKind
  1397. LONGINT theGadNum
  1398. SHORTINT bevelBoxMode
  1399.  
  1400.   '..Render the window.
  1401.   SetWdwRect
  1402.   ID = wdwID-1
  1403.   IF ID = toolWdw THEN ID = 9  '..wrap around?
  1404.   IF wdwFlags AND 2 THEN
  1405.     '..Moveable, so need a title bar.
  1406.     WINDOW ID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1407.   ELSE
  1408.     IF wdwTitle <> "" THEN
  1409.       '..A title has been specified.
  1410.       WINDOW ID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1411.     ELSE
  1412.       '..No title specified.
  1413.       WINDOW ID,,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1414.     END IF
  1415.   END IF
  1416.  
  1417.   '..Set up menu.
  1418.   MENU mProject,iProject,sEnable,    "Project"
  1419.   MENU mProject,iExit,sEnable,        "Exit", "E"
  1420.  
  1421.   '..Render gadgets and text.
  1422.   IF guiObjList = null THEN
  1423.     MsgBox "GUI Object List is not initialised!","Continue"
  1424.   ELSE
  1425.     '..Traverse the list rendering objects.
  1426.     theGadNum = 256
  1427.     curr = guiObjList->nextNode
  1428.     WHILE curr <> null
  1429.       IF curr->kind = staticText THEN
  1430.     '..Text.
  1431.     FONT CSTR(curr->fontName),curr->fontHeight
  1432.     STYLE curr->textStyle
  1433.     COLOR curr->frontColor,curr->backColor
  1434.         PENUP
  1435.     IF curr->theText <> null THEN
  1436.       SETXY curr->x1,curr->y2
  1437.       PRINT CSTR(curr->theText);
  1438.         END IF    
  1439.       ELSE
  1440.     objKind = curr->kind
  1441.     IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  1442.       '..Bevel-Box.
  1443.       IF objKind = raisedBevelBox THEN 
  1444.         bevelBoxMode = RAISED 
  1445.       ELSE
  1446.         bevelBoxMode = RECESSED
  1447.       END IF
  1448.       BEVELBOX (curr->x1,curr->y1)-(curr->x2,curr->y2),bevelBoxMode
  1449.     ELSE
  1450.       '..Gadget.
  1451.       x1 = curr->x1 : y1 = curr->y1
  1452.       x2 = curr->x2 : y2 = curr->y2
  1453.       
  1454.           objKind = curr->kind
  1455.         
  1456.       '..Are offsets required for this gadget?
  1457.       IF objKind = buttonGadget THEN
  1458.         ++x2
  1459.         ++y2
  1460.       ELSE
  1461.         IF objKind = stringGadget OR objKind = longintGadget THEN
  1462.           x1 = x1+6 : y1 = y1+3
  1463.           x2 = x2+6 : y2 = y2+3
  1464.         END IF
  1465.       END IF
  1466.  
  1467.           --theGadNum     
  1468.  
  1469.       IF curr->kind <> potXGadget AND curr->kind <> potYGadget THEN
  1470.          GADGET theGadNum,ON,CSTR(curr->theText),(x1,y1)-(x2,y2),objKind
  1471.       ELSE
  1472.          GADGET theGadNum,ON,curr->potVal,(x1,y1)-(x2,y2),objKind
  1473.       END IF
  1474.         END IF
  1475.       END IF
  1476.       curr = curr->nextNode
  1477.     WEND
  1478.     
  1479.     '..Await Exit item selection from Project menu or close-gadget click.
  1480.     REPEAT
  1481.       MENU WAIT
  1482.     UNTIL (MENU(0) = mProject AND MENU(1) = iExit) OR GADGET(1) = 256
  1483.  
  1484.     '..Clean up.    
  1485.     FOR n=255 TO theGadNum STEP -1
  1486.       GADGET CLOSE n
  1487.     NEXT
  1488.     WINDOW CLOSE ID
  1489.   END IF  
  1490. END SUB
  1491.  
  1492. SUB ToggleFlag(SHORTINT theItem)
  1493. SHARED wdwFlags
  1494. SHORTINT theFlag
  1495.   theFlag = CINT(2^(theItem-iSizeGadget))
  1496.   IF wdwFlags AND theFlag THEN 
  1497.     '..Set flag
  1498.     wdwFlags = wdwFlags - theFlag
  1499.   ELSE
  1500.     '..Reset flag
  1501.     wdwFlags = wdwFlags OR theFlag
  1502.   END IF
  1503. END SUB
  1504.  
  1505. SUB SetWdwID
  1506. SHARED wdwID, dirty
  1507. SHORTINT newID
  1508. STRING wdwIDStr SIZE 2
  1509.   wdwIDStr = STR$(wdwID)
  1510.   wdwIDStr = LTRIM$(wdwIDStr)
  1511.   newID = InputBox("New window ID (2..9)","Set window ID",wdwIDStr,170,10)
  1512.   IF newID <> wdwID AND newID >= 2 AND newID <= 9 THEN
  1513.     dirty = newID <> wdwID
  1514.     SetWdwRect
  1515.     CloseProject
  1516.     wdwID = newID
  1517.     CreateWindow
  1518.     SetUpMenus
  1519.   END IF
  1520. END SUB
  1521.  
  1522. SUB SetWdwTitle
  1523. SHARED wdwID, wdwTitle, dirty
  1524. STRING newTitle SIZE 100
  1525.   newTitle = InputBox$("New window Title?","Set window Title",wdwTitle,170,10)  
  1526.   IF newTitle <> wdwTitle THEN
  1527.     dirty = newTitle <> wdwTitle
  1528.     wdwTitle = newTitle
  1529.     SetWdwRect
  1530.     CloseProject
  1531.     CreateWindow
  1532.     SetUpMenus
  1533.   END IF
  1534. END SUB
  1535.  
  1536. SUB ModifyWindow(SHORTINT theItem)
  1537. SHARED dirty
  1538.   IF theItem >= iSizeGadget THEN 
  1539.     CALL ToggleFlag(theItem)
  1540.     IF NOT dirty THEN dirty = true
  1541.     SetWdwRect
  1542.     CloseProject
  1543.     CreateWindow
  1544.     SetUpMenus
  1545.   ELSE
  1546.     CASE 
  1547.       theItem = iSetID    : SetWdwID
  1548.       theItem = iSetTitle : SetWdwTitle
  1549.     END CASE
  1550.   END IF
  1551. END SUB
  1552.  
  1553. SUB DrawBox(SHORTINT objKind, ADDRESS theCoord)
  1554. SHARED wdwID
  1555. ADDRESS RPort
  1556. SHORTINT xDiff,yDiff, x,y, firstX,firstY
  1557. DECLARE STRUCT CoordType *coord
  1558.  
  1559.   coord = theCoord
  1560.  
  1561.   WINDOW OUTPUT wdwID
  1562.   RPort = WINDOW(8)
  1563.  
  1564.   '..Await a mouse click in the requester window.
  1565.   WHILE NOT MOUSE(0):SLEEP FOR .02:WEND
  1566.  
  1567.   '..Go no further if user didn't click in requester window.
  1568.   IF WINDOW(0) <> wdwID THEN
  1569.     coord->valid = false
  1570.     EXIT SUB 
  1571.   END IF
  1572.  
  1573.   firstX = MOUSE(1) : firstY = MOUSE(2)
  1574.  
  1575.   IF MOUSE(0) THEN
  1576.     SetDrMd(RPort,2)    '..XOR mode
  1577.  
  1578.     WHILE MOUSE(0)
  1579.       x = MOUSE(1) : y = MOUSE(2)
  1580.       xDiff = x-firstX : yDiff = y-firstY
  1581.       IF xDiff > 0 AND yDiff > 0 THEN 
  1582.      COLOR 1:PENUP:SETXY firstX,firstY:PENDOWN
  1583.     SETXY x,firstY:SETXY x,y:SETXY firstX,y:SETXY firstX,firstY
  1584.         ShowMouseCoordinates(firstX,firstY,x,y)
  1585.     COLOR 0:PENUP:SETXY firstX,firstY:PENDOWN
  1586.     SETXY x,firstY:SETXY x,y:SETXY firstX,y:SETXY firstX,firstY
  1587.       END IF
  1588.     WEND    
  1589.       
  1590.     SetDrMd(RPort,1)    '..JAM2 mode
  1591.  
  1592.     ResetReqWdwTitle
  1593.   
  1594.     IF xDiff > 0 AND yDiff > 0 THEN
  1595.       IF objKind = staticText THEN
  1596.     '..Text.
  1597.     DrawTextLayoutGuide(firstX,firstY,x,y)
  1598.     coord->valid = true   
  1599.       ELSE
  1600.     '..Gadget.
  1601.         CASE
  1602.           objKind = buttonGadget     : boxStyle = RAISED
  1603.           objKind = stringGadget     : boxStyle = STRGAD
  1604.           objKind = longintGadget    : boxStyle = STRGAD
  1605.           objKind = potXGadget       : boxStyle = RAISED
  1606.           objKind = potYGadget       : boxStyle = RAISED
  1607.       objKind = raisedBevelBox   : boxStyle = RAISED
  1608.       objKind = recessedBevelBox : boxStyle = RECESSED
  1609.         END CASE
  1610.  
  1611.      BEVELBOX (firstX,firstY)-(x,y),boxStyle
  1612.       coord->valid = true
  1613.       END IF
  1614.  
  1615.       '..Return coordinate info' for object.
  1616.       coord->x1 = firstX : coord->y1 = firstY
  1617.       coord->x2 = x : coord->y2 = y 
  1618.     ELSE
  1619.       coord->valid = false
  1620.     END IF
  1621.   ELSE
  1622.     coord->valid = false
  1623.   END IF
  1624. END SUB
  1625.  
  1626. SUB ADDRESS GUIObjVal(ADDRESS guiObjAddr, STRING prompt)
  1627. SHARED wdwID
  1628. DECLARE STRUCT GUIObjType *guiObj
  1629. DECLARE STRUCT FontInfo info
  1630. ADDRESS textAddress, RPort
  1631. SHORTINT objKind
  1632. STRING tmpString
  1633. STRING defaultString
  1634.  
  1635.   guiObj = guiObjAddr 
  1636.   objKind = guiObj->kind
  1637.  
  1638.   IF objKind <> potXGadget AND objKind <> potYGadget THEN
  1639.     IF guiObj->theText <> null THEN 
  1640.     defaultString = CSTR(guiObj->theText)
  1641.     ELSE
  1642.         defaultString = ""
  1643.     END IF
  1644.     IF objKind = longintGadget THEN
  1645.       '..Want to allow only entry of digits 0..9!
  1646.       textAddress = SADD(LTRIM$(STR$(InputBox(prompt,,defaultString,170,10))))
  1647.     ELSE
  1648.       textAddress = SADD(InputBox$(prompt,,defaultString,170,10))
  1649.     END IF
  1650.  
  1651.     guiObj->theText = ALLOC(LEN(CSTR(textAddress))+1)
  1652.     IF guiObj->theText = null THEN 
  1653.     MsgBox "Memory allocation error!","Continue"
  1654.     GUIObjVal = null
  1655.     ELSE
  1656.         STRING theText ADDRESS guiObj->theText
  1657.         theText = CSTR(textAddress)
  1658.         GUIObjVal = guiObj->theText
  1659.     END IF
  1660.  
  1661.     IF objKind = staticText THEN
  1662.       IF FontInfoRequest(info) THEN
  1663.     '..Okay -> use info' from requester.
  1664.     textAddress = info->fontName
  1665.     guiObj->fontHeight = info->fontHeight
  1666.     guiObj->textStyle = info->textStyle
  1667.     guiObj->frontColor = info->frontColor
  1668.     guiObj->backColor = info->backColor
  1669.       ELSE
  1670.     '..Use defaults.
  1671.         textAddress = SADD("topaz")
  1672.         guiObj->fontHeight = 8
  1673.         guiObj->textStyle = 0
  1674.         guiObj->frontColor = 1
  1675.         guiObj->backColor = 0
  1676.       END IF
  1677.  
  1678.       '..Copy the font name.
  1679.       guiObj->fontName = ALLOC(LEN(CSTR(textAddress))+1)
  1680.       IF guiObj->fontName = null THEN 
  1681.     MsgBox "Memory allocation error!","Continue"
  1682.     GUIObjVal = null
  1683.       ELSE
  1684.         STRING fontName ADDRESS guiObj->fontName
  1685.         fontName = CSTR(textAddress)
  1686.       END IF
  1687.  
  1688.       '..Adjust text selection box.
  1689.       guiObj->y1 = guiObj->y2 - guiObj->fontHeight
  1690.       WINDOW OUTPUT wdwID
  1691.       RPort = WINDOW(8)
  1692.       FONT CSTR(guiObj->fontName),guiObj->fontHeight
  1693.       IF CSTR(guiObj->theText) = "" THEN
  1694.     '..Make sure selection box is big enough to use!
  1695.     tmpString = "M"  '..use a wide character.
  1696.     length = 1
  1697.       ELSE
  1698.         tmpString = CSTR(guiObj->theText)
  1699.         length = LEN(tmpString)
  1700.       END IF
  1701.       guiObj->x2 = guiObj->x1 + TextLength(RPort,tmpString,length)
  1702.     END IF
  1703.   ELSE
  1704.     '..POTX or POTY.
  1705.     REPEAT
  1706.       IF guiObj->potVal > 0 THEN 
  1707.     defaultString = LTRIM$(STR$(guiObj->potVal))
  1708.       ELSE
  1709.     defaultString = ""
  1710.       END IF
  1711.       guiObj->potVal = InputBox(prompt,,defaultString,170,10)
  1712.     UNTIL guiObj->potVal > 0
  1713.     GUIObjVal = guiObj->potVal
  1714.   END IF
  1715. END SUB
  1716.  
  1717. SUB CreateGUIObj(SHORTINT objKind, SHORTINT boxStyle)
  1718. SHARED wdwID, dirty
  1719. DECLARE STRUCT CoordType coord
  1720. DECLARE STRUCT GUIObjType *guiObj
  1721. STRING prompt SIZE 30
  1722.  
  1723.   WINDOW OUTPUT toolWdw
  1724.   GADGET objKind,OFF
  1725.   WINDOW OUTPUT wdwID
  1726.    
  1727.   DrawBox(objKind, coord)
  1728.  
  1729.   IF coord->valid THEN
  1730.     guiObj = NewGUIObj
  1731.     guiObj->kind = objKind
  1732.     guiObj->x1 = coord->x1
  1733.     guiObj->y1 = coord->y1
  1734.     guiObj->x2 = coord->x2
  1735.     guiObj->y2 = coord->y2
  1736.  
  1737.     IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  1738.         '..Add bevel-box object to the list and set the "dirty" 
  1739.     '..flag since the layout has changed.
  1740.         AddGUIObj(guiObj)
  1741.         IF NOT dirty THEN dirty = true      
  1742.     ELSE
  1743.       CASE
  1744.         objKind = buttonGadget  : prompt = "Enter Button Text"
  1745.         objKind = stringGadget  : prompt = "Enter Default Text"
  1746.         objKind = longintGadget : prompt = "Enter Default Value" 
  1747.         objKind = potXGadget    : prompt = "Enter Maximum Slider Value (> 0)"
  1748.         objKind = potYGadget    : prompt = "Enter Maximum Slider Value (> 0)" 
  1749.         objKind = staticText    : prompt = "Enter Static Text"
  1750.       END CASE    
  1751.  
  1752.       IF GUIObjVal(guiObj, prompt) <> null THEN       
  1753.         '..The GUI object is valid so add it to the list
  1754.         '..and set the "dirty" flag since the layout has changed.
  1755.         AddGUIObj(guiObj)
  1756.         IF NOT dirty THEN dirty = true
  1757.  
  1758.         '..Redraw text layout guide now that we have font, style and color,
  1759.         '..having previously adjusted the selection box.
  1760.         IF objKind = staticText THEN
  1761.           WINDOW OUTPUT wdwID
  1762.           CLS : RedrawGUIObjects
  1763.         END IF
  1764.       END IF
  1765.     END IF
  1766.   END IF
  1767.   
  1768.   '..Restore gadget imagery in tool window.
  1769.   WINDOW OUTPUT toolWdw
  1770.   FOR n = gButton TO gRecessedBox : GADGET n,ON : NEXT
  1771.   WINDOW OUTPUT wdwID
  1772. END SUB
  1773.  
  1774. {*
  1775. ** Main.
  1776. *}
  1777. '..Initialise GUI object list.
  1778. IF GUIObjListHead = null THEN STOP
  1779.  
  1780. '..Initialise tool bar button text array.
  1781. InitToolBarButtonText
  1782.  
  1783. '..Initialise main window cross-hair mouse pointer.
  1784. InitCrossHairPointerData
  1785.  
  1786. '..Set up initial project.
  1787. wdwID = 9
  1788. wdw_x1 = 170 : wdw_y1 = 50 : old_wdw_x1 = wdw_x1 : old_wdw_y1 = wdw_y1
  1789. wdw_x2 = 470 : wdw_y2 = 175
  1790. gadCount = 0
  1791. toolBarActive = false : finished = false
  1792.  
  1793. CreateWindow
  1794. SetupMenus
  1795.  
  1796. '..Activate event trapping.
  1797. ON MENU GOSUB handle_menu : MENU ON
  1798. ON GADGET GOSUB handle_gadget : GADGET ON
  1799. ON WINDOW GOSUB handle_window : WINDOW ON
  1800. ON MOUSE GOSUB handle_mouse : MOUSE ON
  1801.  
  1802. '..Await events.
  1803. WHILE NOT finished
  1804.   SetCurrWdw
  1805.   SLEEP FOR .02
  1806. WEND
  1807.  
  1808. '..Deactivate event trapping.
  1809. MENU OFF : GADGET OFF : WINDOW OFF : MOUSE OFF
  1810.  
  1811. '..Clean up.
  1812. CloseProject
  1813. IF toolBarActive THEN CALL ToggleToolBar
  1814. CLEAR ALLOC
  1815. STOP
  1816.  
  1817. {*
  1818. ** Event handlers.
  1819. *}
  1820.  
  1821. {* Menu handler *}
  1822. handle_menu:
  1823.   theMenu = MENU(0)
  1824.   theItem = MENU(1)
  1825.  
  1826.   '..Project menu?
  1827.   IF theMenu = mProject THEN
  1828.     CASE
  1829.     theItem = iNew       : NewProject
  1830.     theItem = iOpen    : OpenProject
  1831.     theItem = iSave    : SaveProject
  1832.     theItem = iSaveAs  : SaveAs
  1833.     theItem = iToolBar : ToggleToolBar
  1834.     theItem = iAbout   : MsgBox "ReqEd v1.12, by David J Benn","Continue"
  1835.     theItem = iQuit       : QuitProgram
  1836.     END CASE
  1837.     RETURN
  1838.   END IF
  1839.  
  1840.   '..Window menu?
  1841.   IF theMenu = mWindow THEN
  1842.     CASE 
  1843.       theItem = iRedraw : WINDOW OUTPUT wdwID:CLS:RedrawGUIObjects
  1844.       theItem = iPreview : PreviewRequester    
  1845.       default : IF theItem <> 0 THEN CALL ModifyWindow(theItem)
  1846.     END CASE
  1847.     RETURN
  1848.   END IF  
  1849.  
  1850. '..No menu.
  1851. RETURN
  1852.  
  1853. {* Window (close-gadget) handler *}
  1854. handle_window:
  1855.   IF WINDOW(0) = toolWdw THEN CALL ToggleToolBar
  1856. RETURN
  1857.  
  1858. {* Gadget handler (for Tool Bar) *}
  1859. handle_gadget:
  1860.   theGadget = GADGET(1) 
  1861.  
  1862.   CASE
  1863.     theGadget = gButton      : boxStyle = RAISED
  1864.     theGadget = gString      : boxStyle = STRGAD
  1865.     theGadget = gLongInt     : boxStyle = STRGAD
  1866.     theGadget = gPotX           : boxStyle = RAISED
  1867.     theGadget = gPotY          : boxStyle = RAISED
  1868.     theGadget = gText          : boxStyle = NORMAL
  1869.     theGadget = gRaisedBox   : boxStyle = RAISED
  1870.     theGadget = gRecessedBox : boxStyle = RECESSED
  1871.   END CASE
  1872.  
  1873.   CreateGUIObj(theGadget, boxStyle)
  1874. RETURN
  1875.  
  1876. {* Mouse-handler (left mouse-button click) *}
  1877. handle_mouse:
  1878. ADDRESS theObject
  1879. SHORTINT edge
  1880.   IF WINDOW(0) = wdwID THEN
  1881.     '..Get current mouse coordinates.
  1882.     mouseX = MOUSE(1) : mouseY = MOUSE(2)
  1883.     '..On a GUI object's border? If so, resize object from specified edge.
  1884.     theObject = OnGUIObjBorder(mouseX, mouseY, @edge)
  1885.     IF theObject <> null THEN
  1886.     ResizeGUIObj(theObject, edge) 
  1887.     ELSE
  1888.         '..Within a GUI object's bounds?
  1889.         theObject = InsideGUIObj(mouseX, mouseY)
  1890.         IF theObject <> null THEN
  1891.             '..Show the object as being selected.
  1892.             SelectGUIObj(theObject)
  1893.           theKey$ = INKEY$
  1894.             CASE
  1895.         theKey$ = CHR$(DEL_key) OR theKey$ = CHR$(BKSPC_key) : DeleteGUIObj(theObject)
  1896.             theKey$ = CHR$(ENTER_key) : ModifyGUIObjVal(theObject)
  1897.             default : MoveGUIObj(theObject)
  1898.           END CASE    
  1899.         END IF
  1900.     END IF
  1901.   END IF
  1902. RETURN
  1903.  
  1904. END
  1905.